/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "GameScene.h"

#include "SceneObject.h"
#include "CameraObject.h"

#include "GlobalVariables.h"
#include "ClientConfig.h"

#include "PlayerUnit.h"

#include "InputSystem.h"

namespace PQClient
{
	GameScene* GameScene::_gameScene=0;

	GameScene::GameScene(SceneId id,Ogre::SceneType sceneType) : _id(id),_sceneObject(0),_loaded(false)
	{
		assert(_id>=0&&_id<Scene_Count);

		Ogre::RenderWindow* win=(Ogre::RenderWindow*)Ogre::Root::getSingletonPtr()->getRenderTarget(CLINET_RENDER_WINDOW_NAME);
		//create scene object
		//should use SceneObject::create() static method to 
		_sceneObject=new PQEngine::SceneObject(win,sceneType);
		
		_gameScene=this;

		Ogre::String keyName="KeyListener"+Ogre::StringConverter::toString(this->getId());
		Ogre::String mouseName="MouseListener"+Ogre::StringConverter::toString(this->getId());

		InputSystem::getSingleton().addKeyListener(this,keyName);
		InputSystem::getSingleton().addMouseListener(this,mouseName);
	}

	void	GameScene::setState(RunningState state)
	{
		Globals.setRunningState(_id,state);
	}

	RunningState GameScene::getState()
	{
		return Globals.getRunningState(_id);
	}


	void GameScene::setActiveSceneId(SceneId id)
	{
		Globals.setActiveSceneId(id);
	}

	bool GameScene::legalSceneId(SceneId id)
	{
		if(id>=Scene_Unkown&&id<Scene_Count){
			return true;
		}
		return false;
	}

	/*Update the game scene
	*/
	void GameScene::update(float deltaT)
	{
		_sceneObject->update(deltaT);
	}

	/*Activate the game scene
	*/
	void GameScene::activate()
	{
		_sceneObject->activate();
		if(_loaded){
			return;
		}
		this->loadScene();
		_loaded=true;
		_gameScene=this;
		
	}

	//now we hard code the unit tobe player unit
	Unit* GameScene::loadUnit(Ogre::String name,Unit::Type type)
	{
		Unit* unit=0;
		//now we direct load unit
		
		switch(type){
			case Unit::Unit_Player_Alchemist:
			case Unit::Unit_Player_Destroyer:
			case Unit::Unit_Player_Vanquisher:
				unit=new PlayerUnit(name,this->getSceneObject(),type);
				break;
		}

		if(unit){
			//save unit
			_units.insert(std::map<Ogre::String,Unit*>::value_type(unit->getName(),unit));
		}

		_activeUnit=unit;
		return unit;
	}

	void GameScene::loadScene(Ogre::String fileName)
	{
		//_sceneObject->getRenderProperty().setBackground(Ogre::ColourValue(0.5,0.5,0.5));
		_sceneObject->getRenderProperty().setAmbient(Ogre::ColourValue(0.5,0.5,0.5));


		setupLights("GameScene.lights.xml");
		setupStaticObjects("GameScene.lights.xml");
		setupDynamicObjects("GameScene.lights.xml");

		setupCamera("GameScene.camera.xml");

	}

	void GameScene::setupLights(Ogre::String configFileName)
	{
		/*
		// add a bright light above the scene
		Light* light = mSceneMgr->createLight();
		light->setType(Light::LT_POINT);
		light->setPosition(-10, 40, 20);
		light->setSpecularColour(ColourValue::White);
		*/
	}

	void GameScene::setupStaticObjects(Ogre::String configFileName)
	{
	}

	void GameScene::setupDynamicObjects(Ogre::String configFileName)
	{
		//load player unit

		loadUnit("Destroyer",Unit::Unit_Player_Destroyer);
		loadUnit("Vanquisher",Unit::Unit_Player_Vanquisher);
		loadUnit("Alchemist",Unit::Unit_Player_Alchemist);
	}

	Unit* GameScene::getUnit(Ogre::String name)
	{
		Unit* unit=0;
		std::map<Ogre::String,Unit*>::iterator it;
		it=_units.find(name);
		if(it!=_units.end()){
			unit=it->second;
		}

		return unit;
	}

	void GameScene::setupCamera(Ogre::String fileName)
	{
		//setup camera
		PQEngine::CameraObject *camera=_sceneObject->getCameraObject();
		camera->setDirection(Ogre::Vector3(0,-0.2,-1));
		Unit* unit=getUnit("Destroyer");
		Ogre::Vector3 cameraPos=camera->getPositionOfFrameObject(unit->getMeshObject(),4.0f);
		camera->setPosition(cameraPos);

		/*
		Ogre::SceneNode *targetNode=player->getSceneNode();
		Ogre::SceneNode *cameraNode=camera->getSceneNode();
		
		Ogre::Real height=player->getBoundingBoxSize().y;

		Ogre::Vector3 targetPos=targetNode->getPosition()+Ogre::Vector3(0,height/2,0);
		Ogre::Vector3 cameraPos=cameraNode->getPosition()+Ogre::Vector3(0,5,8);
		Ogre::Vector3 vec=targetPos-cameraPos;
		cameraNode->setDirection(vec);
		*/

	}

	SceneObject* GameScene::getSceneObject()
	{
		return _sceneObject;
	}

}
